package com.aca.market.service.impl;

import com.aca.market.entity.Cart;
import com.aca.market.entity.Item;
import com.aca.market.entity.User;
import com.aca.market.mapper.CartMapper;
import com.aca.market.mapper.ItemMapper;
import com.aca.market.service.ICartService;
import com.aca.market.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Future;

/**
 * <p>
 * 购物车表 服务实现类
 * </p>
 *
 * @author aca
 * @since 2020-11-16
 */
@Service(value = "cartService")
@Transactional
@Slf4j
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {

    @Autowired
    CartMapper cartMapper;
    @Autowired
    ItemMapper itemMapper;
    @Autowired
    IUserService userService;


    @Override
    public Integer checkCartAmount(){
        if (userService.nowUser() == null) return 0;
        Integer count = cartMapper.selectCount(new QueryWrapper<Cart>()
                .eq("user_id", userService.nowUser().getId()));
        log.info("======>checkCartAmount: {}",count);
        return count;
    }

    @Override
    public Map<Item,Integer> getUserCart(){

        Session session = userService.nowSession();
        System.out.println("session:"+session);
        //获取当前用户
        User user = userService.nowUser();
        Map<Item,Integer> map = new TreeMap<>(Comparator.comparingLong(Item::getId));
        if (user == null) return map;
        //拿到该用户购物车(所有商品id和数量)
        List<Cart> carts = cartMapper.selectList(new QueryWrapper<Cart>().eq("user_id", user.getId()));
        log.info("===========购物车： "+carts.toString());
        for (Cart cart : carts) {
            Item item = itemMapper.selectById(cart.getItemId());
            map.put(item, cart.getCount());
        }
        //更新session购物车 ClassCastException: Cannot deserialize session attribute
        session.setAttribute("cart"+user.getId().toString(),map);
        //反馈到页面上显示购物车内商品数量
        session.setAttribute("cartCount",carts.size());
        return map;
    }

    @Override
    //防止写被打乱
    public String addToCart(Item item){
        //获取当前用户
        User user = userService.nowUser();
        if (user == null) return "no-auth";
        //分情况：1 购物车已经有了，加数量即可 2 没有
        //不判空用户了 shiro过滤 不登陆无法访问
        //1 查数量 有就加数量
        Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>()
                .eq("user_id", user.getId())
                .eq("item_id",item.getId())
                //加锁
                .last("for update"));
        if ( cart!= null && cart.getCount() > 0){
            //不设时区也是东八时间
            log.info(LocalDateTime.now()+">>>>>>>>>>>>>>>>>>>>>购物车有，更新");
            cartMapper.update(cart,new UpdateWrapper<Cart>()
                    .set("count",cart.getCount()+1)
                    .set("update_time",LocalDateTime.now())
                    //时间戳
                    .eq("update_time",cart.getUpdateTime())
                    .eq("user_id", user.getId())
                    .eq("item_id",item.getId()));

            return "update";
        }else {
            log.info(LocalDateTime.now()+">>>>>>>>>>>>>>>>>>>>>购物车没有，添加");
            //2 购物车内没有 加一行
            synchronized (this){
                cartMapper.insert(new Cart(
                        0L,
                        user.getId(),
                        item.getId(),
                        1,
                        LocalDateTime.now(),
                        LocalDateTime.now()));
            }
            return "insert";
        }
    }

    @Override
    @Async("asyncServiceExecutor")
    public synchronized Future<Boolean> addItemQty(Item item){
        //获取当前用户
        User user = userService.nowUser();
        if (user == null) return new AsyncResult<>(Boolean.FALSE);
        //分情况：1 购物车已经有了，加数量即可 2 没有
        //不判空用户了 shiro过滤 不登陆无法访问
        //1 查数量 有就加数量
        Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>()
                .eq("user_id", user.getId())
                .eq("item_id",item.getId()));

        //购物车内归0添加操作 和小按钮共用api
        if (cart == null || cart.getCount() < 0){
            return new AsyncResult<>(cartMapper.insert(new Cart()
                    .setItemId(item.getId())
                    .setUserId(user.getId())
                    .setCreateTime(LocalDateTime.now())
                    .setUpdateTime(LocalDateTime.now())
                    .setCount(1)) > 0);
        } else{
            //不设时区也是东八时间
            log.info(LocalDateTime.now()+">>>>>>>>>>>>>>>>>>>>>购物车有，+1");
            return new AsyncResult<>(cartMapper.update(cart,new UpdateWrapper<Cart>()
                    .set("count",cart.getCount()+1)
                    .set("update_time",LocalDateTime.now())
                    .eq("user_id", user.getId())
                    .eq("item_id",item.getId()))>0);

        }
    }


    @Override
    @Async("asyncServiceExecutor")
    public synchronized Future<Boolean> cutItemQty(Item item){
        //获取当前用户
        User user = userService.nowUser();
        if (user == null) return new AsyncResult<>(Boolean.FALSE);
        //分情况：1 购物车已经有了，加数量即可 2 没有
        //不判空用户了 shiro过滤 不登陆无法访问
        //1 查数量 有就加数量
        Cart cart = cartMapper.selectOne(new QueryWrapper<Cart>()
                .eq("user_id", user.getId())
                .eq("item_id",item.getId()));
        if (cart == null || cart.getCount() <= 0){
            return new AsyncResult<>(Boolean.FALSE);
        }else{
            log.info(LocalDateTime.now()+">>>>>>>>>>>>>>>>>>>>>购物车有，-1");
            return new AsyncResult<>(cartMapper.update(cart,new UpdateWrapper<Cart>()
                    .set("count",cart.getCount()-1)
                    .set("update_time",LocalDateTime.now())
                    .eq("user_id", user.getId())
                    .eq("item_id",item.getId())) > 0);
        }
    }

    @Override
    @Async("asyncServiceExecutor")
    public synchronized Future<Boolean> delItem(Item item){
        //获取当前用户
        User user = userService.nowUser();
        if (user == null) return new AsyncResult<>(Boolean.FALSE);
        return new AsyncResult<>(cartMapper.delete(new QueryWrapper<Cart>()
                .eq("item_id",item.getId())
                .eq("user_id", user.getId())) > 0);
    }


}
